package com.ruoyi.trackapply;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.exception.ProcessStopException;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.ExecUtil;
import com.ruoyi.common.utils.SceneUtil;
import com.ruoyi.common.utils.SseEmitterUtils;
import com.ruoyi.common.utils.ZipUtils;
import com.ruoyi.common.utils.biz.BizModule;
import com.ruoyi.common.utils.biz.PathUtil;
import com.ruoyi.common.utils.biz.ResultSaveModule;
import com.ruoyi.dm.component.manager.TrackDataManager;
import com.ruoyi.dm.domain.po.SpaceTargetMeasurePO;
import com.ruoyi.dm.service.ISpaceTargetMeasureService;
import com.ruoyi.system.domain.ResultSave;
import com.ruoyi.system.service.IResultSaveService;
import com.ruoyi.trackapply.domain.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 轨道定轨效应评估
 */
@Service
@Slf4j
public class OrbitDeterminationService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IResultSaveService resultSaveService;


    @Autowired
    private TrackDataManager trackDataManager;

    private List<String> elements = ListUtil.of("X", "Y", "Z", "VX", "VY", "VZ");

    @Autowired
    private ISpaceTargetMeasureService spaceTargetMeasureService;

    public synchronized OrbitDeterminationVO cal(OrbitDeterminationParam param) throws Exception {
        //进度指示
        int percent = 1;
        SseEmitterUtils.sendMessage(param.getSseId(),++percent+"0");
        List<String> models = param.getModel();
        List<XbfVO> xbfList = new ArrayList<>();
        List<OcVO> ocList = new ArrayList<>();
        List<OribtVO> oribtList = new ArrayList<>();
        List<String> timeList = new ArrayList<>();
        List<EstimateResVO> estimateList = new ArrayList<>();

        List<DateTime> times = SceneUtil.deal(param.getScene());
        DateTime obsStart = times.get(0);
        DateTime obsEnd = times.get(1);

        //1 依据 卫星名称,空间目标测量数据表  查询卫星属性 并写入 /code/dgdq-algorithm/taskAssess/To16OD0708/data/starNetOD/satConst.json
        LambdaQueryWrapper<SpaceTargetMeasurePO> measureQw = new LambdaQueryWrapper<>();
        measureQw.select(SpaceTargetMeasurePO::getCode, SpaceTargetMeasurePO::getName, SpaceTargetMeasurePO::getDens, SpaceTargetMeasurePO::getWindArea, SpaceTargetMeasurePO::getFIndex, SpaceTargetMeasurePO::getLightIndex);
        measureQw.eq(SpaceTargetMeasurePO::getName, param.getSateName());
        SpaceTargetMeasurePO measure = spaceTargetMeasureService.getOne(measureQw);
        if (null == measure) {
            throw new ServiceException("未找到 "+param.getSateName()+" 的目标测量数据,请先去目标测量页面增加数据!");
        }

        ForceModelBO forceModelBO = new ForceModelBO();
        forceModelBO.setArea(Double.valueOf(measure.getWindArea()));
        forceModelBO.setCr(Double.valueOf(measure.getLightIndex()));
        forceModelBO.setCd(Double.valueOf(measure.getFIndex()));
        if (StringUtils.hasLength(param.getWindModel())) {
            switch (param.getWindModel()) {
                case "HWM07":
                    forceModelBO.setWindFieldModel(1);
                    break;
                case "HWCM":
                    forceModelBO.setWindFieldModel(2);
                    //获取风场文件
                    String dataPath = execHwcm(param);
                    forceModelBO.setWindFieldDATA(dataPath);
                    break;
                default:
                    forceModelBO.setWindFieldModel(0);
            }
        }

        //GNSSFileDirPath路径 要去数据库筛选 观测 起止 时间内的 并写入
        List<CollectGnssPO> gnnsPos = trackDataManager.queryGnns(null, measure.getName().toUpperCase(), obsStart, obsEnd);
        if (CollectionUtil.isEmpty(gnnsPos)) {
            throw new ServiceException("未找到数据:"+measure.getName());
        }
        log.info("找到 {}-{}  GNNS数据:{}", obsStart, obsEnd, null != gnnsPos ? gnnsPos.size() : 0);
        //List<CollectGnssPO> gnnsPos = jdbcTemplate.queryForList(String.format(queryGnnsSql, "TEST", measure.getName().toUpperCase(), obsStart, obsEnd), CollectGnssPO.class);
        File gnnsFile = new File(PathUtil.tmpModuleDir(BizModule.TRACK_APPLY), "gnns/"+UUID.fastUUID().toString(true)+"/GNNS.txt");
        gnnsFile.getParentFile().mkdirs();
        FileUtil.writeLines(gnnsPos, gnnsFile, "utf-8");

        JSONConfig jsonConfig = JSONConfig.create().setIgnoreCase(false);
        jsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");

        SseEmitterUtils.sendMessage(param.getSseId(),++percent+"0");
        //2 写入input.json

        //历元时刻
        DateTime calenderStart = DateUtil.offset(obsStart, DateField.DAY_OF_MONTH, 1);
        DateTime calenderEnd = DateUtil.offset(obsEnd, DateField.DAY_OF_MONTH, 1);
        DgInputJsonBO dgInputJsonBO = new DgInputJsonBO();
        dgInputJsonBO.setAlgoDirPath("/dgdq/code/dgdq-algorithm/taskAssess/To16OD0708/data/starNetOD/");
        dgInputJsonBO.setStartEpoch(calenderStart);
        dgInputJsonBO.setEndEpoch(calenderEnd);
        dgInputJsonBO.setObsStartEpoch(obsStart);
        dgInputJsonBO.setObsEndEpoch(obsEnd);


        //从数据库获取 查2个时间间隔  单位秒
        int step = trackDataManager.queryStep(gnnsPos);
        dgInputJsonBO.setStep(step);
        dgInputJsonBO.setSatId(Integer.valueOf(measure.getCode()));
        dgInputJsonBO.setSatName(measure.getName());
        dgInputJsonBO.setSatMass(Double.valueOf(measure.getDens()));
        String inputJson = JSONUtil.toJsonStr(MapBuilder.create().put("Input", dgInputJsonBO).build(), jsonConfig);
        log.info("定轨 inputJson 命令:{}", inputJson);
        String inputJsonPath = PathUtil.tmpModuleDir(BizModule.TRACK_APPLY) + "/" + UUID.fastUUID().toString() + ".json";
        File inoutJsonFile = FileUtil.writeString(inputJson, inputJsonPath, StandardCharsets.UTF_8);

        List<String> resList = new ArrayList<>();

        //每个模型 串行执行
        for (String model : models) {
            //1.HADCAM(大气动态修正模型)；2.HALAM（高精度构建模型）；3.NRLMSISE-00 ；4.Jacchia71；5.JB2008 ；6.DTM2020。
            if ("HADCAM".equals(model)) {
                forceModelBO.setDensityModel(1);
            } else if ("HALAM".equals(model)) {
                forceModelBO.setDensityModel(2);
            } else if ("NRLMSISE-00".equals(model)) {
                forceModelBO.setDensityModel(3);
            } else if ("Jacchia71".equals(model)) {
                forceModelBO.setDensityModel(4);
            } else if ("JB2008".equals(model)) {
                forceModelBO.setDensityModel(5);
            }else if ("DTM2020".equals(model)) {
                forceModelBO.setDensityModel(6);
            }else {
                throw new ServiceException("无效的模型名称:"+model);
            }

            SatConstBO satConstBO = new SatConstBO();
            satConstBO.setGNSSFileDirPath(gnnsFile.getParent());
            satConstBO.setForceModel(forceModelBO);

            String satJson = JSONUtil.toJsonStr(MapBuilder.create().put("Input", satConstBO).build(), jsonConfig);
            log.info("定轨 satJson 命令:{}", satJson);
            String satJsonStr = "/dgdq/code/dgdq-algorithm/taskAssess/To16OD0708/data/starNetOD/satConst.json";
            FileUtil.writeString(satJson, satJsonStr, StandardCharsets.UTF_8);

            //3调用算法
            String script = PathUtil.codeModuleDir(BizModule.TASK_ASSESS) + PathUtil.moduleDirs().getTaskAssess().get("dg");
            String commond = String.format("cd /dgdq/code/dgdq-algorithm/taskAssess/To16OD0708/bin && python %s %s", script, inputJsonPath);
            log.info("定轨命令:{}", commond);
            //String res = RuntimeUtil.execForStr(commond);
            List<String> resLines = ExecUtil.execPythonZw(Stream.of("bash", "-c", commond).collect(Collectors.toList()), param.getSseId());
            String res = CollectionUtil.join(resLines, "\n");
            log.info("定轨命令结果:{}", res);
            resList.add(res);
            //4 获取数据并拼装
            //MSE 均方差    MAE平均绝对误差    RMSE 均方根误差
            /**
             * ###
             * /dgdq/code/dgdq-algorithm/taskAssess/To16OD0708/data/starNetOD//outReport/20240710055346/GNSS_O-C.TXT
             * /dgdq/code/dgdq-algorithm/taskAssess/To16OD0708/data/starNetOD//outReport/20240710055346/GNSS_XBF.TXT
             * /dgdq/code/dgdq-algorithm/taskAssess/To16OD0708/data/starNetOD//outReport/20240710055346/GNSS_ORBIT.TXT
             * ###
             * {'X_MSE': 1.4629722414989591e-05, 'Y_MSE': 9.117140874392815e-06, 'Z_MSE': 1.6249340735600202e-06, 'VX_MSE': 2.741903539208885e-13, 'VY_MSE': 1.77996738376128e-13, 'VZ_MSE': 9.170117973629434e-14}
             * {'X_MAE': -2.7550312283136913e-05, 'Y_MAE': 0.0003071478140180429, 'Z_MAE': 0.0006758501040943789, 'VX_MAE': 1.2794587092297017e-07, 'VY_MAE': 5.287300485773769e-08, 'VZ_MAE': 6.803608605135322e-08}
             * {'X_RMSE': 0.003824882013211596, 'Y_RMSE': 0.003019460361454148, 'Z_RMSE': 0.001274729019658696, 'VX_RMSE': 5.236318877999014e-07, 'VY_RMSE': 4.2189659678187496e-07, 'VZ_RMSE': 3.0282202650450373e-07}
             */
            String[] lines = res.split("[#\r\n]+");
            String ocFile = lines[1];
            Object[] objects = makeupOcVO(ocFile, obsStart, model);
            OcVO vo = (OcVO) objects[0];
            if (CollectionUtil.isEmpty(timeList)) {
                timeList = (List) objects[1];
            }
            ocList.add(vo);
            String xbfFile = lines[2];
            XbfVO xbfVO = makeupXbfVO(xbfFile, model);
            xbfList.add(xbfVO);
            String orbitFile = lines[3];
            OribtVO oribtVO = makeupOribtVO(orbitFile, model);
            oribtList.add(oribtVO);
            String mseStr = lines[4];
            JSONObject mseObj = JSONUtil.parseObj(mseStr);
            String maeStr = lines[5];
            JSONObject maeObj = JSONUtil.parseObj(maeStr);
            String rmseStr = lines[6];
            JSONObject rmseObj = JSONUtil.parseObj(rmseStr);
            for (String element : elements) {
                EstimateResVO build = EstimateResVO.builder()
                        .mae(new BigDecimal(maeObj.getStr(element + "_MAE")))
                        .mse(new BigDecimal(mseObj.getStr(element + "_MSE")))
                        .rmse(new BigDecimal(rmseObj.getStr(element + "_RMSE")))
                        .model(model).param(element).build();
                estimateList.add(build);
            }
            //给算法缓冲时间
            //进度指示
            SseEmitterUtils.sendMessage(param.getSseId(),++percent+"0");
            Thread.sleep(1100);
        }
        inoutJsonFile.delete();
        //将结果缓存
        redisTemplate.opsForValue().set(MD5.create().digestHex(param.toString()), JSONUtil.toJsonStr(resList), 1, TimeUnit.HOURS);

        OrbitDeterminationBO bo = new OrbitDeterminationBO();
        bo.setOc(ocList);
        bo.setXbf(xbfList);
        bo.setOribt(oribtList);
        bo.setTime(timeList);
        bo.setEstimate(estimateList);

        OrbitDeterminationVO vo = dealWithReturn(bo);
        SseEmitterUtils.sendMessage(param.getSseId(),++percent+"0");
        //FileUtil.del(gnnsFile.getParentFile());
        return vo;
    }

    /**
     * 调用风场算法
     * @return
     */
    private String execHwcm(OrbitDeterminationParam param) throws ProcessStopException {
        String script = PathUtil.codeModuleDir(BizModule.MODEL_REVISE) + PathUtil.moduleDirs().getTaskAssess().get("hwcm");
        //写文件
        // {
        //"setfile":"/dgdq/config/common.ini",
        //"filepath":"/dgdq/output/collect/result/wind",
        //"outfile":"/dgdq/output/modelRevise/orbit_call",
        //"dataname":"Nimbus-7",
        //"datatype":"None",
        //"revised_cycle":"5",
        //"point":"/dgdq/output/modelRevise/average_model/20240829143912lonLatH.txt",
        //"intertype":"linear"
        //}
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("setfile","");
        paramMap.put("filepath","");
        paramMap.put("outfile","");
        paramMap.put("dataname","");
        paramMap.put("datatype","");
        paramMap.put("revised_cycle","");
        paramMap.put("point","");
        paramMap.put("intertype","");
        String jsonPath = "";
        FileUtil.writeString("", jsonPath, Charset.forName("utf-8"));
        List<String> resList = ExecUtil.execPythonZw(ListUtil.of(script, jsonPath), param.getSseId());
        if (null != resList) {
            for (String line : resList) {
                if (line.startsWith("###")) {
                    String[] split = line.split("###");
                    return split[1];
                }
            }
        }
        return null;
    }

    //页面 返回特定的格式
    private OrbitDeterminationVO dealWithReturn(OrbitDeterminationBO bo) {
        OrbitDeterminationVO resVO = new OrbitDeterminationVO();
        resVO.setTime(bo.getTime());
        resVO.setEstimate(bo.getEstimate());
        //定轨误差
        Map<String, Object> ocxyz = new HashMap<>();
        for (OcVO vo : bo.getOc()) {
            String model = vo.getModel();
            ocxyz.put(model + "_x", vo.getX());
            ocxyz.put(model + "_y", vo.getY());
            ocxyz.put(model + "_z", vo.getZ());
        }
        resVO.setOcXyz(ocxyz);
        Map<String, Object> ocv = new HashMap<>();
        for (OcVO vo : bo.getOc()) {
            String model = vo.getModel();
            ocv.put(model + "_vx", vo.getVx());
            ocv.put(model + "_vy", vo.getVy());
            ocv.put(model + "_vz", vo.getVz());
        }
        resVO.setOcV(ocv);

        //地固系定轨数据
        Map<String, Object> xbfXyz = new HashMap<>();
        for (XbfVO vo : bo.getXbf()) {
            String model = vo.getModel();
            xbfXyz.put(model + "_x", vo.getX());
            xbfXyz.put(model + "_y", vo.getY());
            xbfXyz.put(model + "_z", vo.getZ());

        }
        resVO.setXbfXyz(xbfXyz);
        Map<String, Object> xbfV = new HashMap<>();
        for (XbfVO vo : bo.getXbf()) {
            String model = vo.getModel();
            xbfV.put(model + "_vx", vo.getVx());
            xbfV.put(model + "_vy", vo.getVy());
            xbfV.put(model + "_vz", vo.getVz());
        }
        resVO.setXbfV(xbfV);

        //定轨六根数
        Map<String, Object> orbitBcz = new HashMap<>();
        for (OribtVO vo : bo.getOribt()) {
            String model = vo.getModel();
            orbitBcz.put(model + "_半长轴", vo.getBcz());
            orbitBcz.put("unit", "m");

        }
        resVO.setOribtBcz(orbitBcz);
        Map<String, Object> orbitPxl = new HashMap<>();
        for (OribtVO vo : bo.getOribt()) {
            String model = vo.getModel();
            orbitPxl.put(model + "_偏心率", vo.getPxl());
            orbitPxl.put("unit", "");

        }
        resVO.setOribtPxl(orbitPxl);
        Map<String, Object> orbitQj = new HashMap<>();
        for (OribtVO vo : bo.getOribt()) {
            String model = vo.getModel();
            orbitQj.put(model + "_倾角", vo.getQj());
            orbitQj.put("unit", "deg");

        }
        resVO.setOribtQj(orbitQj);
        Map<String, Object> orbitSjd = new HashMap<>();
        for (OribtVO vo : bo.getOribt()) {
            String model = vo.getModel();
            orbitSjd.put(model + "_升交点赤经", vo.getSjd());
            orbitSjd.put("unit", "deg");

        }
        resVO.setOribtSjd(orbitSjd);
        Map<String, Object> orbitJdd = new HashMap<>();
        for (OribtVO vo : bo.getOribt()) {
            String model = vo.getModel();
            orbitJdd.put(model + "_近地点辐角", vo.getJdd());
            orbitJdd.put("unit", "deg");

        }
        resVO.setOribtJdd(orbitJdd);
        Map<String, Object> orbitPjdd = new HashMap<>();
        for (OribtVO vo : bo.getOribt()) {
            String model = vo.getModel();
            orbitPjdd.put(model + "_平近点角", vo.getPjdd());
            orbitPjdd.put("unit", "deg");

        }
        resVO.setOribtPjdd(orbitPjdd);
        return resVO;
    }

    public void save(OrbitDeterminationParam param) {
        List<String> dataList = resByParam(param);
        param.setSseId(null);
        List<DateTime> times = SceneUtil.deal(param.getScene());
        DateTime obsStart = times.get(0);
        DateTime obsEnd = times.get(1);
        ResultSave entity = ResultSave.builder()
                .params("")
                .module(ResultSaveModule.TRACK_APPLY)
                .submodule(ResultSaveModule.TRACK_APPLY_DG)
                .resultData(JSONUtil.toJsonStr(dataList))
                .startTime(DateUtil.format(obsStart,"yyyy-MM-dd"))
                .endTime(DateUtil.format(obsEnd,"yyyy-MM-dd"))
                .createTime(new Date())
                .build();
        resultSaveService.resultSave(param,entity);
    }

    /**
     * 通过参数 查询结果缓存
     * @param param
     * @return
     */
    private List<String> resByParam(OrbitDeterminationParam param) {
        String cachRes = (String)redisTemplate.opsForValue().get(MD5.create().digestHex(param.toString()));
        if (!StringUtils.hasLength(cachRes)) {
            throw new ServiceException("请先计算后再保存");
        }

        JSONArray catArray = JSONUtil.parseArray(cachRes);
        /**
         * ###
         * /dgdq/code/dgdq-algorithm/taskAssess/To16OD0708/data/starNetOD//outReport/20240710055346/GNSS_O-C.TXT
         * /dgdq/code/dgdq-algorithm/taskAssess/To16OD0708/data/starNetOD//outReport/20240710055346/GNSS_XBF.TXT
         * /dgdq/code/dgdq-algorithm/taskAssess/To16OD0708/data/starNetOD//outReport/20240710055346/GNSS_ORBIT.TXT
         * ###
         * {'X_MSE': 1.4629722414989591e-05, 'Y_MSE': 9.117140874392815e-06, 'Z_MSE': 1.6249340735600202e-06, 'VX_MSE': 2.741903539208885e-13, 'VY_MSE': 1.77996738376128e-13, 'VZ_MSE': 9.170117973629434e-14}
         * {'X_MAE': -2.7550312283136913e-05, 'Y_MAE': 0.0003071478140180429, 'Z_MAE': 0.0006758501040943789, 'VX_MAE': 1.2794587092297017e-07, 'VY_MAE': 5.287300485773769e-08, 'VZ_MAE': 6.803608605135322e-08}
         * {'X_RMSE': 0.003824882013211596, 'Y_RMSE': 0.003019460361454148, 'Z_RMSE': 0.001274729019658696, 'VX_RMSE': 5.236318877999014e-07, 'VY_RMSE': 4.2189659678187496e-07, 'VZ_RMSE': 3.0282202650450373e-07}
         */
        List<String> dataList = new ArrayList<>();

        for (Object o : catArray) {
            String res = (String)o;
            String[] lines = res.split("[#\r\n]+");
            List<String> jsonList = new ArrayList<>();
            dataList.add(lines[1]);
            dataList.add(lines[2]);
            dataList.add(lines[3]);
            //将属性json 写入文件,再保存到datelist
            jsonList.add(lines[4]);
            jsonList.add(lines[5]);
            jsonList.add(lines[6]);
            String jsons = JSONUtil.toJsonStr(jsonList);
            File tmpFile = new File(lines[1]);
            File file = FileUtil.writeString(jsons, new File(tmpFile.getParentFile(),"评估.json"), "utf-8");
            dataList.add(file.getAbsolutePath());
        }
        return dataList;
    }

    public File download(OrbitDeterminationParam param) throws IOException {

        List<String> dataList = resByParam(param);
        String timeStr = DateUtil.format(new Date(), "yyyyMMddHHmmss");
        String zipPath = RuoYiConfig.getDownloadPath() + "/轨道定轨效应评估-"+timeStr+".zip";
        ZipUtils.zipWithPath(dataList,zipPath);
        return new File(zipPath);
    }

    /**
     * 组装OcVO返回值
     * 因为时间都一样，故只处理一次， 返回  [oc, 时间数组, ]
     *
     * @param filePath 文件路径
     * @param model
     * @return
     * @throws Exception
     */
    private Object[] makeupOcVO(String filePath, Date obsTime, String model) throws Exception {
        //获取行数
        File file = new File(filePath);
        long lines = Files.lines(Paths.get(file.getPath())).count();
        //页面展示1000条数据
        int num = 1000;
        int skip = 1;
        if (lines > 1000) {
            skip = (int) (lines / num);
        }
        List<String> timeList = new ArrayList<>(110);
        List<BigDecimal> xList = new ArrayList<>(110);
        List<BigDecimal> yList = new ArrayList<>(110);
        List<BigDecimal> zList = new ArrayList<>(110);
        List<BigDecimal> vxList = new ArrayList<>(110);
        List<BigDecimal> vyList = new ArrayList<>(110);
        List<BigDecimal> vzList = new ArrayList<>(110);
        BufferedReader reader = new BufferedReader(new FileReader(file));
        int lineNum = 0;
        String line = "";
        while (null != (line = reader.readLine())) {
            //60S  ObsStartEpoch为起点
            //      0.0000        -0.0039        -0.0032        -0.0022     0.00000028    -0.00000006     0.00000047
            if (lineNum % skip == 0) {
                String[] split = line.trim().split("\\s+");
                DateTime offset = DateUtil.offset(obsTime, DateField.SECOND, (Double.valueOf(split[0]).intValue()));
                String format = DateUtil.format(offset, "yyyy-MM-dd HH:mm:ss");
                timeList.add(format);
                xList.add(new BigDecimal(split[1]).setScale(3,BigDecimal.ROUND_HALF_UP));
                yList.add(new BigDecimal(split[2]).setScale(3,BigDecimal.ROUND_HALF_UP));
                zList.add(new BigDecimal(split[3]).setScale(3,BigDecimal.ROUND_HALF_UP));
                vxList.add(new BigDecimal(split[4]).setScale(8,BigDecimal.ROUND_HALF_UP));
                vyList.add(new BigDecimal(split[5]).setScale(8,BigDecimal.ROUND_HALF_UP));
                vzList.add(new BigDecimal(split[6]).setScale(8,BigDecimal.ROUND_HALF_UP));
            }
            lineNum++;
        }

        OcVO oc = new OcVO();
        oc.setModel(model);
        oc.setX(xList);
        oc.setY(yList);
        oc.setZ(zList);
        oc.setVx(vxList);
        oc.setVy(vyList);
        oc.setVz(vzList);
        return new Object[]{oc, timeList};
    }

    /**
     * 组装OcVO返回值
     *
     * @param filePath 文件路径
     * @param model
     * @return
     * @throws Exception
     */
    private OribtVO makeupOribtVO(String filePath, String model) throws Exception {
        //获取行数
        File file = new File(filePath);
        long lines = Files.lines(Paths.get(file.getPath())).count();
        //页面展示1000条数据
        int num = 1000;
        int skip = 1;
        if (lines > 1000) {
            skip = (int) (lines / num);
        }
        List<String> timeList = new ArrayList<>(110);
        List<BigDecimal> xList = new ArrayList<>(110);
        List<BigDecimal> yList = new ArrayList<>(110);
        List<BigDecimal> zList = new ArrayList<>(110);
        List<BigDecimal> vxList = new ArrayList<>(110);
        List<BigDecimal> vyList = new ArrayList<>(110);
        List<BigDecimal> vzList = new ArrayList<>(110);
        BufferedReader reader = new BufferedReader(new FileReader(file));
        int lineNum = 0;
        String line = "";
        while (null != (line = reader.readLine())) {
            //2024  02  25  02  40    0.00000        42166130.420          0.00094784          7.62501504         63.17893877        306.76733775        270.86194280
            if (lineNum % skip == 0) {
                String[] split = line.split("\\s+");
                LocalDateTime of = LocalDateTime.of(Integer.valueOf(split[0]), Integer.valueOf(split[1]), Integer.valueOf(split[2]), Integer.valueOf(split[3]), Integer.valueOf(split[4]));
                timeList.add(of.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
                xList.add(new BigDecimal(split[6]).setScale(3,BigDecimal.ROUND_HALF_UP));
                yList.add(new BigDecimal(split[7]).setScale(3,BigDecimal.ROUND_HALF_UP));
                zList.add(new BigDecimal(split[8]).setScale(3,BigDecimal.ROUND_HALF_UP));
                vxList.add(new BigDecimal(split[9]).setScale(8,BigDecimal.ROUND_HALF_UP));
                vyList.add(new BigDecimal(split[10]).setScale(8,BigDecimal.ROUND_HALF_UP));
                vzList.add(new BigDecimal(split[11]).setScale(8,BigDecimal.ROUND_HALF_UP));
            }
            lineNum++;
        }

        OribtVO vo = new OribtVO();
        vo.setModel(model);
        vo.setBcz(xList);
        vo.setPxl(yList);
        vo.setQj(zList);
        vo.setSjd(vxList);
        vo.setJdd(vyList);
        vo.setPjdd(vzList);
        return vo;
    }

    /**
     * 组装XbfVO返回值
     *
     * @param filePath 文件路径
     * @param model
     * @return
     * @throws Exception
     */
    private XbfVO makeupXbfVO(String filePath, String model) throws Exception {
        //获取行数
        File file = new File(filePath);
        long lines = Files.lines(Paths.get(file.getPath())).count();
        //页面展示1000条数据
        int num = 1000;
        int skip = 1;
        if (lines > 1000) {
            skip = (int) (lines / num);
        }
        List<String> timeList = new ArrayList<>(110);
        List<BigDecimal> xList = new ArrayList<>(110);
        List<BigDecimal> yList = new ArrayList<>(110);
        List<BigDecimal> zList = new ArrayList<>(110);
        List<BigDecimal> vxList = new ArrayList<>(110);
        List<BigDecimal> vyList = new ArrayList<>(110);
        List<BigDecimal> vzList = new ArrayList<>(110);
        BufferedReader reader = new BufferedReader(new FileReader(file));

        int lineNum = 0;
        String line = "";
        while (null != (line = reader.readLine())) {
            //  2022 01 19 00 01 00.000000    2171511.020   -3920771.756   -5223573.771    2692.421204   -5107.103490    4940.691249
            if (lineNum % skip == 0) {
                String[] split = line.trim().split("\\s+");
                Calendar instance = Calendar.getInstance();
                instance.set(Integer.valueOf(split[0]),Integer.valueOf(split[1]),Integer.valueOf(split[2]),Integer.valueOf(split[3]),Integer.valueOf(split[4]),Double.valueOf(split[5]).intValue());
                timeList.add(DateUtil.format(instance.getTime(),"yyyy-MM-dd HH:mm:ss"));
                xList.add(new BigDecimal(split[6]).setScale(3,BigDecimal.ROUND_HALF_UP));
                yList.add(new BigDecimal(split[7]).setScale(3,BigDecimal.ROUND_HALF_UP));
                zList.add(new BigDecimal(split[8]).setScale(3,BigDecimal.ROUND_HALF_UP));
                vxList.add(new BigDecimal(split[9]).setScale(8,BigDecimal.ROUND_HALF_UP));
                vyList.add(new BigDecimal(split[10]).setScale(8,BigDecimal.ROUND_HALF_UP));
                vzList.add(new BigDecimal(split[11]).setScale(8,BigDecimal.ROUND_HALF_UP));
            }
            lineNum++;
        }

        XbfVO vo = new XbfVO();
        vo.setModel(model);
        vo.setX(xList);
        vo.setY(yList);
        vo.setZ(zList);
        vo.setVx(vxList);
        vo.setVy(vyList);
        vo.setVz(vzList);
        return vo;
    }

}
